﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SpLocalizer.Common;
using Microsoft.SharePoint;
using SpLocalizer.Common.DbApi;
using SpLocalizer.ContentSourceProviders.SpListItems;
using Microsoft.Practices.Unity;


namespace SpLocalizer.ContentSourceProviders
{
    /// <summary>
    /// Project for translation List item values
    /// </summary>
    public class SpListItemsTranslationProject : AbstractTranslationProject, IDisposable
    {

        private SPSite _site = null;
        /// <summary>
        /// Local SharePoint Site project handle
        /// </summary>
        private SPSite Site
        {
            get
            {
                if (this._site == null)
                {
                    this._site = new SPSite(this.ConnectionString);
                }
                return this._site;
            }
        }


        protected override void Bind(bool IncludeDescendants)
        {
            SPListItemContent firstList = new SPListItemContent();
            SPWeb parentWeb = this.Site.OpenWeb();
            SPList list = parentWeb.GetList(this.ConnectionString);

            if (list == null) // We have to translate all lists recursively
            {
                if (!IncludeDescendants)
                {
                    throw new ApplicationException("To translate all web lists you have to check IncludeDescendants");
                }

                BindToAllWebLists(parentWeb);
                this.ProjectTitle = String.Format("All lists content under {0}", this.ConnectionString);
            }
            else
            {
                BindToList(list, parentWeb.ID);
                this.ProjectTitle = String.Format("List {0} content", this.ConnectionString);
            }
        }


        /// <summary>
        /// Bind to all lists in this web and subwebs
        /// </summary>
        /// <param name="web"></param>
        private void BindToAllWebLists(SPWeb web)
        {
            foreach (SPList list in web.Lists)
            {
                BindToList(list, web.ID);
            }
            foreach (SPWeb subWeb in web.Webs)
                BindToAllWebLists(subWeb);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="list"></param>
        private void BindToList(SPList list, Guid parentWeb)
        {
            if (list.HasExternalDataSource || list.Hidden)
                return; /// we don't support localization for BCS lists

                SPListItemContent ListItemProvider = new SPListItemContent();
                ListItemProvider.Bind(list);
                ListItemProvider.ParentContentId = parentWeb.ToString();
                this._ContentData.Add(ListItemProvider);
        }


        protected override AbstractContent LoadContent(LocalizableContent content)
        {
            SPListItemContent ListContent = ServiceContainer.Resolve<AbstractContent>(content.ContentSourceProvider) as SPListItemContent;
            if (ListContent != null) // We have only ione content provider 
            {
                
                ListContent.PropertiesSerializationXml = content.ContentSourceProviderData;
                ListContent.Id = content.Id;
                SPWeb listWeb = this.Site.OpenWeb(new Guid(content.ParentContentId));
                SPList contentList = listWeb.GetList(content.ContentAddress);
                    
                ListContent.Bind(contentList);
                this._ContentData.Add(ListContent);
                return ListContent;
            }
            return null;
        }

        protected override void RegisterContentProviderTypes()
        {
            ServiceContainer.Container.RegisterType<AbstractContent, SPListItemContent>(typeof(SPListItemContent).Name);
            ServiceContainer.Container.RegisterType<BaseTranslationTask, SpListItemStringValueLocalizationTask>(typeof(SpListItemStringValueLocalizationTask).Name);
            ServiceContainer.Container.RegisterType<BaseTranslationTask, SpListItemFieldUrlValueLocalizationTask>(typeof(SpListItemFieldUrlValueLocalizationTask).Name);
            ServiceContainer.Container.RegisterType<BaseTranslationTask, SpListItemLookupValueLocalizationTask>(typeof(SpListItemLookupValueLocalizationTask).Name);
        }

        public void Dispose()
        {
            if (this._site != null)
            {
                this._site.Close();
                this._site = null;
            }
        }
    }
}
